package ae.pcfc.etks.online.web.controller.admin.workflow.general.company.request;

/* $Id: ClientCompanyController.java 
 * Copyright (C) 2011, TRAKHEES
 *  
 * Revision History
 *
 * Date  			Author 		    	Remarks
 * ---------------------------------------------------------------------------------
 * April 11, 2011 	Mohtisham.Salahria	Created
 *
 */


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.UnhandledException;
import org.apache.commons.lang.WordUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.ConstantsCommon.WFProcessType;
import ae.pcfc.etks.online.common.delegate.AdminClientCompanyReviewDelegate;
import ae.pcfc.etks.online.common.delegate.AppMetaDataDelegate;
import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.delegate.UserDelegate;
import ae.pcfc.etks.online.common.delegate.UserReqDelegate;
import ae.pcfc.etks.online.common.util.CommonUtils;
import ae.pcfc.etks.online.common.vo.AdminApprovalVO;
import ae.pcfc.etks.online.common.vo.ClientCompanyReqVO;
import ae.pcfc.etks.online.common.vo.ClientCompanyVO;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.common.vo.SCCompanyVO;
import ae.pcfc.etks.online.common.vo.StepActionVO;
import ae.pcfc.etks.online.common.vo.StepCommentVO;
import ae.pcfc.etks.online.common.vo.UserVO;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.common.Constants;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.model.ClientCompanyRegistration;
import ae.pcfc.etks.online.web.model.RegisterAdminReview;
import ae.pcfc.etks.online.web.util.SecurityUtils;

@Controller
@RequestMapping(ViewPath.ADMIN_GENERAL_COMPANY_REQUEST_CLIENT)
public class AdminClientCompanyController extends BaseController{
	
	
	private AdminClientCompanyReviewDelegate adminClientCompanyReviewDelegate;

	@Resource(name = "adminClientCompanyReviewDelegate")
	public void setAdminClientCompanyReviewDelegate(
			AdminClientCompanyReviewDelegate adminClientCompanyReviewDelegate) {
		this.adminClientCompanyReviewDelegate = adminClientCompanyReviewDelegate;
	}

	private UserReqDelegate userReqDelegate;
	
	@Resource(name = "userReqDelegate")	
	public void setUserReqDelegate(UserReqDelegate userReqDelegate) {
		this.userReqDelegate = userReqDelegate;
	}
	
	private AppMetaDataDelegate appMetaDataDelegate;

	@Resource(name = "appMetaDataDelegate")	
	public void setAppMetaDataDelegate(AppMetaDataDelegate appMetaDataDelegate) {
		this.appMetaDataDelegate = appMetaDataDelegate;
	}
	
	private ClientRegistrationDelegate clientRegistrationDelegate;
	
	@Resource(name = "clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}

	/**
	 * A factory method for creating or loading an existing company.
	 * <p/>
	 * Note that this method is annotated with @ModelAttribute, which means it
	 * will be invoked before every request handling method in this class in
	 * order to pre-create the model object either by loading it or by creating
	 * it from scratch. this method will be invoked before resolving @ModelAttribute
	 * Method Parameter
	 * 
	 * @param id
	 *            an optional parameter specifying the id of the
	 *            ClientCompanyRegistration. If left unspecified a new ClientCompanyRegistration
	 *            is created.
	 * 
	 * @return an instance of an ClientCompanyRegistration model object
	 */
	
	@ModelAttribute(value = ConstantsAdmin.CLIENT_COMPANY_REGISTRATION_ADMIN_REVIEW_USER_DATA_REQUEST_MODEL_KEY)
	public ClientCompanyRegistration populateReferenceData(HttpServletRequest request,
			@RequestParam(value = "id", required = false) String id, @RequestParam(value = "appid", required = false) String appid, Model model) {
		
		if(appid != null)
		{
			ClientCompanyReqVO clientCompanyReqVO = this.userReqDelegate.loadClientCompanyReqByApplicationId(SecurityUtils.decrypt(appid));
			if (clientCompanyReqVO != null)
			{
				ClientCompanyRegistration clientCompanyRegistration = new ClientCompanyRegistration();
				getMapper().map(clientCompanyReqVO, clientCompanyRegistration);
				String trakheesId = clientCompanyReqVO.getStrTrakheesId();
				if(trakheesId == null){
				    throw new UnhandledException("Invalid trakhees Id no: "+ trakheesId, null);
				}
				SCCompanyVO scCompanyVO = this.clientRegistrationDelegate.findSCCompanyByTrakheesId(trakheesId);
				
				if(scCompanyVO == null ){			
					throw new UnhandledException("Invalid trakhees Id no: "+ trakheesId, null);
				} else{
				    model.addAttribute(ConstantsAdmin.CLIENT_COMPANY_REGISTER_SUMMARY_REQUEST_MODEL_KEY, scCompanyVO);
				}
				
				return clientCompanyRegistration;
			}
			
		}
		
		// TODO Here we'll place the logic to load the User Data through an Id
		return new ClientCompanyRegistration();
	}
	
	@ModelAttribute(value = ConstantsAdmin.ADMIN_ACTION_HISTORY_REQUEST_MODEL_KEY)
	public AdminApprovalVO populateActionHistory(HttpServletRequest request, @RequestParam(value = "appid", required = false) String appid) {
		
		if(appid != null)
		{
			AdminApprovalVO adminApprovalVO = appMetaDataDelegate.loadAppMetaData(SecurityUtils.decrypt(appid));
			return (adminApprovalVO==null)?new AdminApprovalVO():adminApprovalVO;
		}
		
		// TODO Here we'll place the logic to load the User Data through an Id
		return new AdminApprovalVO();
	}
	
	@ModelAttribute(ConstantsAdmin.NON_CLIENT_PERSON_REGISTER_ACTION_TYPE_LIST_REQUEST_MODEL_KEY)
	public List<LabelVO> populateActionTypeListModel(Locale locale) {

		List<LabelVO> labelList = new ArrayList<LabelVO>();

		LabelVO labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.APPROVE);	
		labelVO.setLabelAr(getMessageSource().getMessage("label.admin.approve", null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage("label.admin.approve", null, locale));
		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId(ConstantsCommon.REJECT);
		labelVO.setLabelAr(getMessageSource().getMessage("label.admin.reject", null, locale));
		labelVO.setLabelEn(getMessageSource().getMessage("label.admin.reject", null, locale));
		labelList.add(labelVO);

		return labelList;
	}
	/*@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(@RequestParam(value = "appid", required = true) String appid,
			@RequestParam(value = "UserName", required = true) String userName,
			@RequestParam(value = "TaskID", required = true) String taskID,
			@RequestParam(value = "Incident", required = true) String incident,
			@RequestParam(value = "StepName", required = true) String stepName,
			@RequestParam(value = "StepCode", required = true) String stepCode,
			@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) RegisterAdminReview adminReview) {
		adminReview.setStrApplicationId(appid);
		adminReview.setStrUserName(userName);
		adminReview.setStrTaskId(taskID);
		adminReview.setStrIncidentNo(incident);
		adminReview.setStrStepName(stepName);
		adminReview.setDepartment(UtilCommon.getDepartmentFromStepCode(stepCode));
	}*/
	@RequestMapping(value = "/form.htm", method = RequestMethod.GET)
	public void form(HttpServletRequest request,
		@RequestParam(value = "appid", required = true) String appid,
		@RequestParam(value = "Incident", required = true) String incident,
		@RequestParam(value = "StepName", required = true) String stepName,
		@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) RegisterAdminReview adminReview) {
	    	adminReview.setStrApplicationId(appid);
		String userName = request.getRemoteUser();
		if(!StringUtils.isBlank(userName)){
			userName=WordUtils.capitalize(userName.toLowerCase(),new char[]{'.'});
			// TEMPORARY FIX - Code added to make sure user name is matching with one in Active directory(case sensitive)
		    final String DOT_SEPERATOR = "."; 
		    final String MIDDLE_NAME = "Al";
		    if(StringUtils.startsWith(StringUtils.substringAfter(userName,DOT_SEPERATOR), MIDDLE_NAME))		    		
		    {
		    	String tempLastName = StringUtils.substringAfter(userName,DOT_SEPERATOR);	
		    	tempLastName = MIDDLE_NAME+WordUtils.capitalize(StringUtils.substringAfter(tempLastName,MIDDLE_NAME));
		    	userName = StringUtils.substringBefore(userName,DOT_SEPERATOR)+DOT_SEPERATOR+tempLastName;
		    }
		    // End TEMP FIX
		    adminReview.setStrUserName(CommonUtils.appendDomainPrefix(userName));
		}
		adminReview.setStrIncidentNo(SecurityUtils.decrypt(incident));
		stepName = SecurityUtils.decrypt(stepName);
		adminReview.setStrStepName(stepName);
		// delete 'REVIEW' from 'CED Review' and trim 
		//adminReview.setDepartment(StringUtils.trim(StringUtils.remove(stepName.toUpperCase(), ConstantsCommon.PROCESS_STEP_REVIEW).toUpperCase()));
	}
	@RequestMapping(value = "/show.htm", method = RequestMethod.GET)
	public void show(@RequestParam(value = "appid", required = true) String appid) {
	}
	/**
	 * Custom handler for displaying the form, i.e.: POST requests for
	 * /admin/general/company/request/client/form.
	 * <p/>
	 * Note that this handler returns void instead of a {@link ModelAndView},
	 * signifying a default logical view name should be selected by Spring MVC.
	 * The ui {@link Model} is supplied as a parameter to the method and
	 * populated with the new company registration object to be rendered.
	 * 
	 * @see #form(HttpServletRequest,SessionStatus,NonClientPersonRegisterPeronalInfo,
	 *      BindingResult)
	 * @see WEB-INF/jsp/admin/general/company/request/client/form.jsp
	 */

	@RequestMapping(method = RequestMethod.POST, value = "/form.htm")
	public String form(
			HttpServletRequest request,
			HttpSession session,
			SessionStatus status,
			@ModelAttribute(value = ConstantsAdmin.REGISTER_ADMIN_REVIEW_REQUEST_MODEL_KEY) @Valid RegisterAdminReview adminReview,
			BindingResult errors) {
                AdminApprovalVO adminVO = new AdminApprovalVO();
        		
                getMapper().map(adminReview, adminVO);
        		//adminVO.setStrProcessCode(ConstantsAdmin.PROCESS_CODE_CLIENT_COMPANY_REGISTRATION);
                adminVO.setProcessCode(WFProcessType.CLIENT_COMPANY_REGISTRATION);
                //adminVO.setStrProcessStep(adminReview.getStrStepName());
                /*if(adminReview != null && adminReview.getDepartment() != null){
        			adminVO.setDepartment(adminReview.getDepartment());
                	adminVO.setStrProcessStep(ConstantsAdmin.PROCESS_STEP_REVIEW_CLIENT_COMPANY + ConstantsCommon.PROCESS_STEP_CODE_CONNECTOR + adminReview.getDepartment());
                }else{
                	adminVO.setStrProcessStep(ConstantsAdmin.PROCESS_STEP_REVIEW_CLIENT_COMPANY);
                }*/
        
		adminVO.setStrApplicationId(SecurityUtils.decrypt(adminReview.getStrApplicationId()));
		adminVO.setActionDate(Calendar.getInstance().getTime());

		
		StepActionVO stepActionVO = new StepActionVO();		
		getMapper().map(adminReview, stepActionVO);
		stepActionVO.setActionDate(Calendar.getInstance().getTime());
		
		StepCommentVO stepCommentVO = new StepCommentVO();		
		getMapper().map(adminReview, stepCommentVO);
		stepCommentVO.setCommentDate(Calendar.getInstance().getTime());
		
		adminVO.setCommentsVOs(new ArrayList<StepCommentVO>(Arrays.asList(stepCommentVO)));
		adminVO.setStepActionVOs(new ArrayList<StepActionVO>(Arrays.asList(stepActionVO)));
		
		
		ClientCompanyReqVO clientCompanyReqVO = this.userReqDelegate.loadClientCompanyReqByApplicationId(adminVO.getStrApplicationId());
		
		UserVO userVO = new UserVO();		
		getMapper().map(clientCompanyReqVO, userVO);
		userVO.setCreateDate(Calendar.getInstance().getTime());
		userVO.setStrType(Constants.USER); 
		
		ClientCompanyVO clientCompanyVO = new ClientCompanyVO();		
		getMapper().map(clientCompanyReqVO, clientCompanyVO);
		
		clientCompanyVO.setUserVOs(new ArrayList<UserVO> (Arrays.asList(userVO)));		
		clientCompanyVO.setCreateDate(Calendar.getInstance().getTime());
		clientCompanyVO.setStrClientType(Constants.COMPANY);
		clientCompanyVO.setStrStatus(Constants.ACTIVE); 
		
		if (adminVO.getStrActionType().equals(ConstantsCommon.APPROVE)) {
			adminVO.setStrStatusEn(getMessageSource().getMessage("msg.workflow.status.approved", null, Locale.ENGLISH));
			adminVO.setStrStatusAr(getMessageSource().getMessage("msg.workflow.status.approved", null, new Locale(Constants.LOCALE_ARABIC)));
		} else if (adminVO.getStrActionType().equals(ConstantsCommon.REJECT)) {
			adminVO.setStrStatusEn(getMessageSource().getMessage("msg.workflow.status.rejected", null, Locale.ENGLISH));
			adminVO.setStrStatusAr(getMessageSource().getMessage("msg.workflow.status.rejected", null, new Locale(Constants.LOCALE_ARABIC)));
		}
		
		adminVO.setStrInProgressStatusEn(getMessageSource().getMessage("msg.workflow.status.in.progress", null, Locale.ENGLISH));
		adminVO.setStrInProgressStatusAr(getMessageSource().getMessage("msg.workflow.status.in.progress", null, new Locale(Constants.LOCALE_ARABIC)));

		adminClientCompanyReviewDelegate.reviewRegisterClientCompany(adminVO, clientCompanyVO);
		
		if(errors.hasErrors()){
			return ViewUtils.DEFAULT_VIEW;
		}
		
		
		status.setComplete();
		session.setAttribute(ConstantsAdmin.SUCCESS_PARAM, getMessageSource().getMessage("success.user.info.edit", null,RequestContextUtils.getLocale(request)));
		
		
		/*if( adminVO != null)
		{
			adminClientPersonReviewDelegate.getMapper().map(nonClientPersonRegisterAdminReview, adminVO);
			adminVO.setStrApplicationId(new Long(request.getParameter("appid")));
			adminVO.setActionDate(new Date());
			
			adminClientPersonReviewDelegate.reviewRegisterClientPerson(adminVO);
			status.setComplete();
			request.setAttribute("success", getMessageSource().getMessage("label.success.registerservice", null,RequestContextUtils.getLocale(request)));
			
		}*/

		return ViewUtils.getRedirect(ViewPath.USER_INTERNAL_TRAKHEES_STAFF_INBOX, PageType.LIST);

	}
	
	private UserDelegate userDelegate;
	
	@Resource(name = "userDelegate")
	public void setUserDelegate(UserDelegate userDelegate) {
		this.userDelegate = userDelegate;
	}
	
	@ModelAttribute(ConstantsAdmin.WORKFLOW_STEPNAME)
	public List<String> getNextStepName(HttpServletRequest request, @RequestParam(value = "Incident", required = true) String incidentNo) {

		return userDelegate.getTaskInformation(Integer.parseInt(SecurityUtils.decrypt(incidentNo)), ConstantsAdmin.PROCESS_CODE_CLIENT_COMPANY_REGISTRATION);
	}
}
